import pygame
import random
import time

# 初始化 Pygame
pygame.init()

# 游戏窗口配置
WIDTH, HEIGHT = 800, 600
BLOCK_SIZE = 20
SPEED = 5

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)

# 创建窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Pygame 贪吃蛇")

# 时钟控制帧率
clock = pygame.time.Clock()

# 字体设置,默认的arial显示不了中文，需要使用指定的微软雅黑字体
try:
    font = pygame.font.Font("resource/Microsoft Yahei.ttf", 24)
except:
    font = pygame.font.SysFont("arial", 24)

# 在初始化部分添加精灵图加载和分割代码
try:
    # 加载精灵图
    spritesheet = pygame.image.load("resource/snake.png").convert_alpha()

    # 定义精灵图中的各个部分的像素值，40像素
    SPRITE_SIZE = BLOCK_SIZE * 2

    # 蛇头方向 (右, 左, 上, 下)
    head_right = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(4 * SPRITE_SIZE, 0, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))
    head_left = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(4 * SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))
    head_up = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(3 * SPRITE_SIZE, 0, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))
    head_down = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(3 * SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))

    # 蛇尾方向 (右, 左, 上, 下)
    tail_right = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(0, SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))
    tail_left = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(SPRITE_SIZE, 0, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))
    tail_up = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))
    tail_down = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(0, 0, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))

    # 蛇身弯角 (左上, 右上, 左下, 右下)
    corner_tl = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(6 * SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))  # 左上
    corner_tr = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(5 * SPRITE_SIZE, 0, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))  # 右上
    corner_bl = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(6 * SPRITE_SIZE, 0, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))  # 左下
    corner_br = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(5 * SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))  # 右下

    # 蛇身直段 (水平, 垂直)
    straight_h = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(2 * SPRITE_SIZE, 0, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))  # 水平
    straight_v = pygame.transform.scale(spritesheet.subsurface(pygame.Rect(2 * SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE)), (BLOCK_SIZE, BLOCK_SIZE))  # 垂直

    # 创建精灵字典
    snake_sprites = {
        "head": {
            "RIGHT": head_right,
            "LEFT": head_left,
            "UP": head_up,
            "DOWN": head_down,
        },
        "tail": {
            "RIGHT": tail_right,
            "LEFT": tail_left,
            "UP": tail_up,
            "DOWN": tail_down,
        },
        "corner": {
            "TL": corner_tl,  # 左上
            "TR": corner_tr,  # 右上
            "BL": corner_bl,  # 左下
            "BR": corner_br,  # 右下
        },
        "straight": {"H": straight_h, "V": straight_v},  # 水平  # 垂直
    }

    print("精灵图加载成功！")
except Exception as e:
    print(f"精灵图加载失败: {str(e)}")
    snake_sprites = None


# 测试显示精灵图
def test_display_sprites():
    """测试显示所有加载的精灵图"""
    # 创建测试窗口
    test_screen = pygame.display.set_mode((1600, 1600))
    pygame.display.set_caption("精灵图测试")

    # 定义显示位置
    x, y = 50, 50
    spacing = SPRITE_SIZE + 10

    # 显示头部精灵
    if snake_sprites:
        # 显示蛇头，文字部分高30像素
        title = font.render("蛇头精灵", True, WHITE)
        test_screen.blit(title, (x, y - 30))
        test_screen.blit(snake_sprites["head"]["RIGHT"], (x, y))
        test_screen.blit(snake_sprites["head"]["LEFT"], (x + spacing, y))
        test_screen.blit(snake_sprites["head"]["UP"], (x + 2 * spacing, y))
        test_screen.blit(snake_sprites["head"]["DOWN"], (x + 3 * spacing, y))

        # 显示尾部精灵
        title = font.render("蛇尾精灵", True, WHITE)
        test_screen.blit(title, (x, y + SPRITE_SIZE))
        test_screen.blit(snake_sprites["tail"]["RIGHT"], (x, y + SPRITE_SIZE + 30))
        test_screen.blit(snake_sprites["tail"]["LEFT"], (x + spacing, y + SPRITE_SIZE + 30))
        test_screen.blit(snake_sprites["tail"]["UP"], (x + 2 * spacing, y + SPRITE_SIZE + 30))
        test_screen.blit(snake_sprites["tail"]["DOWN"], (x + 3 * spacing, y + SPRITE_SIZE + 30))

        # 显示角落精灵
        title = font.render("角落精灵", True, WHITE)
        test_screen.blit(title, (x, y + 2 * SPRITE_SIZE + 30))
        test_screen.blit(snake_sprites["corner"]["TL"], (x, y + 2 * SPRITE_SIZE + 60))  # 左上
        test_screen.blit(snake_sprites["corner"]["TR"], (x + spacing, y + 2 * SPRITE_SIZE + 60))  # 右上
        test_screen.blit(snake_sprites["corner"]["BL"], (x + 2 * spacing, y + 2 * SPRITE_SIZE + 60))  # 左下
        test_screen.blit(snake_sprites["corner"]["BR"], (x + 3 * spacing, y + 2 * SPRITE_SIZE + 60))  # 右下

        # 显示直段精灵
        title = font.render("直段精灵", True, WHITE)
        test_screen.blit(title, (x, y + 3 * SPRITE_SIZE + 60))
        test_screen.blit(snake_sprites["straight"]["H"], (x, y + 3 * SPRITE_SIZE + 90))  # 水平
        test_screen.blit(snake_sprites["straight"]["V"], (x + spacing, y + 3 * SPRITE_SIZE + 90))  # 垂直

        # 添加说明文本
        instructions = [
            "蛇头: RIGHT, LEFT, UP, DOWN",
            "蛇尾: RIGHT, LEFT, UP, DOWN",
            "角落: TL(左上), TR(右上), BL(左下), BR(右下)",
            "直段: H(水平), V(垂直)",
        ]

        for i, text in enumerate(instructions):
            text_surface = font.render(text, True, WHITE)
            test_screen.blit(text_surface, (50, y + 3 * SPRITE_SIZE + 130 + i * 30))

        pygame.display.update()

        # 等待按键退出
        waiting = True
        while waiting:
            for event in pygame.event.get():
                if event.type == pygame.QUIT or event.type == pygame.KEYDOWN:
                    waiting = False

    # 恢复游戏窗口
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("Pygame 贪吃蛇")


class Snake:
    def __init__(self):
        self.body = [
            (WIDTH // 2, HEIGHT // 2),
            (WIDTH // 2 - BLOCK_SIZE, HEIGHT // 2),
            (WIDTH // 2 - BLOCK_SIZE * 2, HEIGHT // 2),
        ]  # 初始位置
        self.direction = "RIGHT"  # 初始方向
        self.grow = False  # 是否增长

    def move(self):
        # 计算新头部位置
        head_x, head_y = self.body[0]
        if self.direction == "UP":
            head_y -= BLOCK_SIZE
        elif self.direction == "DOWN":
            head_y += BLOCK_SIZE
        elif self.direction == "LEFT":
            head_x -= BLOCK_SIZE
        elif self.direction == "RIGHT":
            head_x += BLOCK_SIZE

        # 插入新头部并移除尾部（除非需要增长）
        self.body.insert(0, (head_x, head_y))
        if not self.grow:
            self.body.pop()
        else:
            self.grow = False

    def change_direction(self, new_dir):
        # 防止反向移动
        if (
            (new_dir == "UP" and self.direction != "DOWN")
            or (new_dir == "DOWN" and self.direction != "UP")
            or (new_dir == "LEFT" and self.direction != "RIGHT")
            or (new_dir == "RIGHT" and self.direction != "LEFT")
        ):
            self.direction = new_dir


def generate_food(snake):
    while True:
        food_x = random.randint(0, (WIDTH - BLOCK_SIZE) // BLOCK_SIZE) * BLOCK_SIZE
        food_y = random.randint(0, (HEIGHT - BLOCK_SIZE) // BLOCK_SIZE) * BLOCK_SIZE
        if (food_x, food_y) not in snake.body:
            return (food_x, food_y)


def draw_elements(snake, food, score):
    # 清屏
    screen.fill(BLACK)

    # 绘制蛇 - 使用精灵图
    if snake_sprites and len(snake.body) > 0:
        # 绘制蛇身（从尾部到头部）
        for i in range(len(snake.body) - 1, -1, -1):
            segment = snake.body[i]

            if i == 0:  # 蛇头
                sprite = snake_sprites["head"][snake.direction]
                screen.blit(sprite, segment)

            elif i == len(snake.body) - 1:  # 蛇尾
                prev_segment = snake.body[i - 1]
                if prev_segment[0] > segment[0]:
                    direction = "LEFT"
                elif prev_segment[0] < segment[0]:
                    direction = "RIGHT"
                elif prev_segment[1] > segment[1]:
                    direction = "UP"
                else:
                    direction = "DOWN"
                sprite = snake_sprites["tail"][direction]
                screen.blit(sprite, segment)

            else:  # 中间段
                prev_segment = snake.body[i - 1]
                next_segment = snake.body[i + 1]

                if prev_segment[0] == next_segment[0]:  # 垂直
                    sprite = snake_sprites["straight"]["H"]
                elif prev_segment[1] == next_segment[1]:  # 水平
                    sprite = snake_sprites["straight"]["V"]
                else:  # 弯段
                    if (prev_segment[0] < segment[0] and next_segment[1] < segment[1]) or (prev_segment[1] < segment[1] and next_segment[0] < segment[0]):
                        sprite = snake_sprites["corner"]["TL"]
                    elif (prev_segment[0] > segment[0] and next_segment[1] < segment[1]) or (prev_segment[1] < segment[1] and next_segment[0] > segment[0]):
                        sprite = snake_sprites["corner"]["TR"]
                    elif (prev_segment[0] < segment[0] and next_segment[1] > segment[1]) or (prev_segment[1] > segment[1] and next_segment[0] < segment[0]):
                        sprite = snake_sprites["corner"]["BL"]
                    else:
                        sprite = snake_sprites["corner"]["BR"]
                screen.blit(sprite, segment)
    else:
        # 如果精灵图加载失败，使用默认方块绘制
        for segment in snake.body:
            pygame.draw.rect(
                screen,
                GREEN,
                pygame.Rect(segment[0], segment[1], BLOCK_SIZE, BLOCK_SIZE),
            )

    # 绘制食物
    pygame.draw.rect(screen, RED, pygame.Rect(food[0], food[1], BLOCK_SIZE, BLOCK_SIZE))

    # 显示分数
    score_text = font.render(f"Score: {score}", True, WHITE)
    screen.blit(score_text, (10, 10))


def game_over(screen, score):
    # 游戏结束界面
    screen.fill(BLACK)
    game_over_text = font.render("GAME OVER!", True, WHITE)
    score_text = font.render(f"Final Score: {score}", True, WHITE)
    screen.blit(game_over_text, (WIDTH // 2 - 150, HEIGHT // 2 - 50))
    screen.blit(score_text, (WIDTH // 2 - 120, HEIGHT // 2 + 20))
    pygame.display.update()
    time.sleep(3)


def show_start_screen():
    """显示开始界面，等待任意按键"""
    screen.fill(BLACK)
    start_text = font.render("Press Any Key to Start", True, WHITE)
    screen.blit(start_text, (WIDTH // 2 - 180, HEIGHT // 2))
    pygame.display.update()

    waiting = True
    while waiting:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:  # 检测任意按键
                waiting = False


def show_pause_screen(snake):
    """通过闪烁窗口标题提示游戏已暂停"""
    paused = True
    original_caption = pygame.display.get_caption()  # 保存原始标题
    flash_timer = 0
    print(snake.body)  # 打印蛇的身体位置

    while paused:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                paused = False  # 按空格继续游戏

        # 闪烁标题
        flash_timer += 1
        if flash_timer % 30 < 15:
            pygame.display.set_caption("🎮 Game Paused")
        else:
            pygame.display.set_caption("🎮 Pygame 贪吃蛇")

        pygame.time.delay(50)  # 控制闪烁频率

    # 恢复原始标题
    pygame.display.set_caption(original_caption[0])


def main():
    global SPEED
    snake = Snake()
    food = generate_food(snake)
    score = 0
    running = True

    # test_display_sprites()  # 添加这行

    # 添加开始界面
    show_start_screen()  # 等待按键

    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:  # 按下空格键进入暂停界面
                    show_pause_screen(snake)  # 调用独立暂停界面函数
                elif event.key == pygame.K_UP:
                    snake.change_direction("UP")
                elif event.key == pygame.K_DOWN:
                    snake.change_direction("DOWN")
                elif event.key == pygame.K_LEFT:
                    snake.change_direction("LEFT")
                elif event.key == pygame.K_RIGHT:
                    snake.change_direction("RIGHT")

        # 移动蛇
        snake.move()

        # 碰撞检测
        head = snake.body[0]
        if head[0] < 0 or head[0] >= WIDTH or head[1] < 0 or head[1] >= HEIGHT or head in snake.body[1:]:
            game_over(screen, score)
            return

        # 吃到食物
        if head == food:
            score += 10
            snake.grow = True
            food = generate_food(snake)
            SPEED += 2  # 速度提升

        # 绘制元素
        draw_elements(snake, food, score)
        pygame.display.update()
        clock.tick(SPEED)


if __name__ == "__main__":
    main()
